package com.aaa.tars.service.impl;

import com.aaa.tars.config.PayConfig;
import com.aaa.tars.dao.PayDao;
import com.aaa.tars.entity.Pay;
import com.aaa.tars.service.OrderService;
import com.aaa.tars.service.PayService;
import com.aaa.tars.util.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @FileName: PayServiceImpl
 * @Description: 支付服务实现类，提供支付相关的业务逻辑处理
 * @Author: ghz
 * @CreateTime:2025/9/11 14:59
 * @Version:1.0.0
 */
@Service
public class PayServiceImpl implements PayService {
    // 注入支付数据访问对象
    @Autowired
    @Qualifier("payDao")
    private PayDao payDao;


    @Autowired
    private OrderService orderService;

    @Override
    public Pay getByOrderNo(String orderNo) {
        return payDao.selectByOrderNo(orderNo);
    }

    @Override
    public int insert(Pay pay) {
        pay.setPayTime(new Date());
        return payDao.insert( pay);
    }

    /**
     * 更新支付记录
     * @param pay 支付实体对象
     * @return 受影响的行数
     */
    @Override
    public int update(Pay pay) {
        return payDao.update( pay);
    }

    /**
     * 根据ID删除支付记录
     * @param payId 支付记录ID
     * @return 受影响的行数
     */
    @Override
    public int deleteById(Integer payId) {

        if (payId== null|| payId<=0){
            throw  new CustomException(ResultStatus.ERROR.getStatusCode(),ResultStatus.ERROR.getStatusMessage());
        }
        return payDao.deleteById( payId);
    }

    /**
     * 根据ID查询支付记录
     * @param payId 支付记录ID
     * @return 支付实体对象
     */
    @Override
    public Pay queryById(Integer payId) {
        if (payId== null|| payId<=0){
            throw new CustomException(ResultStatus.ERROR.getStatusCode(),ResultStatus.ERROR.getStatusMessage());
        }
        return payDao.queryById(payId);
    }

    /**
     * 分页查询支付记录
     * @param page 分页参数对象
     * @return 分页信息对象
     */
    @Override
    public PageInfo queryByPage(Page<Pay> page) {
        Integer pageNo = page.getPageNo();
        Integer pageSize = page.getPageSize();
        if (pageNo == null || pageNo <= 0 || pageSize == null || pageSize <= 0) {
            throw new CustomException(ResultStatus.ERROR.getStatusCode(),
                    ResultStatus.ERROR.getStatusMessage());
        }
        // 设置分页参数
        PageHelper.startPage(pageNo, pageSize);
        Pay data = page.getData();
        // 执行查询并返回分页结果
        return new PageInfo(payDao.queryByParam(data));


    }

    // 新增1：创建微信支付预支付单（核心逻辑，直接用Pay类接收参数）
    @Override
    public Map<String, String> createWxPay(Pay pay) throws Exception {
        // 1.1 校验参数（订单号、金额必传）
        if (pay.getOrderNo() == null || pay.getOrderNo().trim().isEmpty()) {
            throw new CustomException(400, "订单号不可为空");
        }
        if (pay.getPayPje() == null || pay.getPayPje() <= 0) {
            throw new CustomException(400, "支付金额必须大于0");
        }

        // 1.2 校验该订单是否已创建支付记录（避免重复创建）
        Pay payQuery = new Pay();
        payQuery.setOrderNo(pay.getOrderNo());
        List<Pay> payList = payDao.queryByParam(payQuery);
        if (payList != null && !payList.isEmpty()) {
            // 如果支付记录已存在，直接返回已有的支付二维码，而不是抛出异常
            Pay existingPay = payList.get(0);
            Map<String, String> returnMap = new HashMap<>();
            // 从已有的支付记录中提取code_url（如果存在）
            if (existingPay.getPayFullmsg() != null) {
                // 尝试从payFullmsg中解析出code_url
                try {
                    Map<String, String> wxResult = WXPayUtil.xmlToMap(existingPay.getPayFullmsg());
                    if (wxResult.containsKey("code_url")) {
                        returnMap.put("code_url", wxResult.get("code_url"));
                        returnMap.put("message", "支付二维码已生成，请扫描付款");
                        return returnMap;
                    } else {
                        // 如果无法解析或没有code_url，则重新生成支付
                        return recreateWxPay(existingPay);
                    }
                } catch (Exception e) {
                    // 解析失败，重新生成支付
                    return recreateWxPay(existingPay);
                }
            } else {
                // 如果没有payFullmsg，则重新生成支付
                return recreateWxPay(existingPay);
            }
        }

        // 1.3 构造微信统一下单参数（金额转分，微信要求）
        Map<String, String> wxParam = new HashMap<>();
        wxParam.put("appid", PayConfig.APPID);
        wxParam.put("mch_id", PayConfig.MCH_ID);
        wxParam.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机字符串
        
        // 限制商品描述长度不超过127字节
        String body = pay.getPayFullmsg() != null ? pay.getPayFullmsg() : "景区订单支付";
        if (body.getBytes("UTF-8").length > 127) {
            // 如果超过127字节，截取前面的部分并添加省略号
            byte[] bytes = body.getBytes("UTF-8");
            int endIndex = 124; // 为省略号预留3个字节
            while (endIndex > 0 && (bytes[endIndex] & 0x80) != 0 && (bytes[endIndex] & 0xC0) != 0xC0) {
                endIndex--; // 避免截断中文字符
            }
            body = new String(bytes, 0, endIndex, "UTF-8") + "...";
        }
        wxParam.put("body", body); // 商品描述（用Pay的payFullmsg字段存储）
        
        wxParam.put("out_trade_no", pay.getOrderNo()); // 商户订单号（Pay的orderNo字段）
        wxParam.put("total_fee", new BigDecimal(pay.getPayPje()).multiply(new BigDecimal("100")).longValue() + ""); // 金额转分
        wxParam.put("spbill_create_ip", "127.0.0.1"); // 终端IP（部署时替换为真实IP）
        wxParam.put("notify_url", "http://localhost:17112/pay/notify"); // 回调地址（虽不用可填默认值）
        wxParam.put("trade_type", "NATIVE"); // 扫码支付类型

        // 1.4 调用微信统一下单接口
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
        client.setXmlParam(WXPayUtil.generateSignedXml(wxParam, PayConfig.API_KEY));
        client.setHttps(true);
        client.post();
        String wxXmlResult = client.getContent();
        
        // 检查返回内容是否为空
        if (wxXmlResult == null || wxXmlResult.isEmpty()) {
            throw new CustomException(500, "微信下单失败：无法获取微信支付响应");
        }
        
        Map<String, String> wxResult = WXPayUtil.xmlToMap(wxXmlResult);

        // 1.5 校验微信返回结果，失败则抛异常
        if (!"SUCCESS".equals(wxResult.get("return_code")) || !"SUCCESS".equals(wxResult.get("result_code"))) {
            String errorMsg = "微信下单失败";
            if (wxResult.containsKey("return_msg")) {
                errorMsg += "：" + wxResult.get("return_msg");
            }
            if (wxResult.containsKey("err_code_des")) {
                errorMsg += " - " + wxResult.get("err_code_des");
            }
            // 特别处理订单号重复的情况
            if (wxResult.containsKey("err_code") && "OUT_TRADE_NO_USED".equals(wxResult.get("err_code"))) {
                errorMsg += "（商户订单号重复）";
                throw new CustomException(500, "该订单已创建支付，请不要重复提交支付请求");
            }
            throw new CustomException(500, errorMsg);
        }

        // 1.6 保存支付记录到数据库（初始状态：未支付）
        pay.setPaySerialno(wxResult.get("prepay_id")); // 微信预支付ID
        pay.setPayResult("0"); // 0=未支付，1=已支付
        pay.setPayRespcode(wxResult.get("return_code"));
        pay.setPayFullmsg(wxXmlResult); // 存储微信返回的完整信息（XML格式）
        pay.setPayTime(new Date());
        payDao.insert(pay);

        // 1.7 返回code_url给前端（用于生成支付二维码）
        Map<String, String> returnMap = new HashMap<>();
        returnMap.put("code_url", wxResult.get("code_url"));
        returnMap.put("message", "支付二维码已生成，请扫描付款");
        return returnMap;
    }

    /**
     * 重新创建微信支付（当已有支付记录但需要重新生成时调用）
     * @param existingPay 已存在的支付记录
     * @return 支付二维码信息
     * @throws Exception
     */
    private Map<String, String> recreateWxPay(Pay existingPay) throws Exception {
        // 如果支付状态已经是成功，则直接返回成功状态
        if ("1".equals(existingPay.getPayResult())) {
            Map<String, String> returnMap = new HashMap<>();
            returnMap.put("message", "该订单已支付成功");
            return returnMap;
        }
        
        // 删除旧的支付记录
        payDao.deleteById(existingPay.getPayId());
        
        // 创建新的支付对象
        Pay newPay = new Pay();
        newPay.setOrderNo(existingPay.getOrderNo());
        newPay.setPayPje(existingPay.getPayPje());
        newPay.setPayFullmsg(existingPay.getPayFullmsg());
        
        // 递归调用createWxPay方法创建新的支付
        return createWxPay(newPay);
    }

    // 新增2：查询支付状态并更新记录（核心逻辑）
    @Override
    public String queryWxPayStatus(String orderNo) throws Exception {
        // 2.1 构造微信查询参数
        Map<String, String> wxParam = new HashMap<>();
        wxParam.put("appid", PayConfig.APPID);
        wxParam.put("mch_id", PayConfig.MCH_ID);
        wxParam.put("out_trade_no", orderNo); // 商户订单号
        wxParam.put("nonce_str", WXPayUtil.generateNonceStr());

        // 2.2 调用微信订单查询接口
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
        client.setXmlParam(WXPayUtil.generateSignedXml(wxParam, PayConfig.API_KEY));
        client.setHttps(true);
        client.post();
        String wxXmlResult = client.getContent();
        
        // 检查返回内容是否为空
        if (wxXmlResult == null || wxXmlResult.isEmpty()) {
            throw new CustomException(500, "查询支付状态失败：无法获取微信支付响应");
        }
        
        Map<String, String> wxResult = WXPayUtil.xmlToMap(wxXmlResult);

        // 2.3 校验查询结果
        if (!"SUCCESS".equals(wxResult.get("return_code"))) {
            String errorMsg = "查询支付状态失败";
            if (wxResult.containsKey("return_msg")) {
                errorMsg += "：" + wxResult.get("return_msg");
            }
            throw new CustomException(500, errorMsg);
        }

        // 2.4 若支付成功，更新支付记录和订单状态
        String tradeState = wxResult.get("trade_state");
        if ("SUCCESS".equals(tradeState)) {
            // 2.4.1 查询该订单的支付记录
            Pay payQuery = new Pay();
            payQuery.setOrderNo(orderNo);
            List<Pay> payList = payDao.queryByParam(payQuery);
            if (payList != null && !payList.isEmpty()) {
                Pay payUpdate = payList.get(0);
                payUpdate.setPayResult("1"); // 标记为已支付
                payUpdate.setPaySerialno(wxResult.get("transaction_id")); // 微信交易流水号
                payUpdate.setPayRespcode("SUCCESS");
                payUpdate.setPayFullmsg(wxResult.toString());
                payUpdate.setPayTime(new Date());
                payDao.update(payUpdate);

                // 2.4.2 同步更新订单状态为"已付款"（orderState=12，需与前端状态值一致）
                // 修改：使用新的更新方法
                orderService.updateOrderStateByNo(orderNo, OrderStateEnum.PAID_SUCCESS);
            }
        }

        return tradeState; // 返回微信支付状态（如SUCCESS/NOTPAY）
    }

}